You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
699 lines
19 KiB
699 lines
19 KiB
import { Ionicons } from '@expo/vector-icons';
|
|
import { useLocalSearchParams, useRouter } from 'expo-router';
|
|
import { useState } from 'react';
|
|
import {
|
|
ActivityIndicator,
|
|
Alert,
|
|
Pressable,
|
|
ScrollView,
|
|
StyleSheet,
|
|
Text,
|
|
TextInput,
|
|
View,
|
|
} from 'react-native';
|
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
import Svg, { Circle, Line, Polygon, Text as SvgText } from 'react-native-svg';
|
|
import { useJobDetail } from '../../src/hooks';
|
|
import { buildJobShareText } from '../../src/api';
|
|
import { shareText } from '../../src/lib/shareFile';
|
|
import { colors } from '../../src/theme';
|
|
import { formatThousands } from '../../src/utils';
|
|
import type { JobDimensionScore } from '../../src/types';
|
|
|
|
/* ===================== 雷达图(6 维度,SVG 绘制) ===================== */
|
|
|
|
/** 六边形雷达图:同心网格 + 轴线 + 数据多边形 + 维度标签 */
|
|
function RadarChart({
|
|
dimensions,
|
|
size = 160,
|
|
}: {
|
|
dimensions: JobDimensionScore[];
|
|
size?: number;
|
|
}) {
|
|
const cx = size / 2;
|
|
const cy = size / 2;
|
|
const count = dimensions.length;
|
|
// 数据/网格最大半径(预留标签空间)
|
|
const R = size / 2 - 36;
|
|
const labelR = R + 16;
|
|
const levels = [0.25, 0.5, 0.75, 1];
|
|
const angleFor = (i: number) => (-90 + i * (360 / count)) * (Math.PI / 180);
|
|
const pointFor = (i: number, ratio: number) => ({
|
|
x: cx + R * ratio * Math.cos(angleFor(i)),
|
|
y: cy + R * ratio * Math.sin(angleFor(i)),
|
|
});
|
|
const polygonPoints = (ratio: number) =>
|
|
dimensions
|
|
.map((_, i) => {
|
|
const p = pointFor(i, ratio);
|
|
return `${p.x},${p.y}`;
|
|
})
|
|
.join(' ');
|
|
|
|
const dataPoints = dimensions.map((d, i) => pointFor(i, d.value / 100));
|
|
|
|
return (
|
|
<Svg width={size} height={size}>
|
|
{/* 同心网格 */}
|
|
{levels.map((ratio) => (
|
|
<Polygon
|
|
key={ratio}
|
|
points={polygonPoints(ratio)}
|
|
fill="none"
|
|
stroke={colors.border}
|
|
strokeWidth={1}
|
|
/>
|
|
))}
|
|
{/* 轴线 */}
|
|
{dimensions.map((_, i) => {
|
|
const p = pointFor(i, 1);
|
|
return (
|
|
<Line key={i} x1={cx} y1={cy} x2={p.x} y2={p.y} stroke={colors.border} strokeWidth={1} />
|
|
);
|
|
})}
|
|
{/* 数据多边形 */}
|
|
<Polygon
|
|
points={dataPoints.map((p) => `${p.x},${p.y}`).join(' ')}
|
|
fill={colors.primary}
|
|
fillOpacity={0.15}
|
|
stroke={colors.primary}
|
|
strokeWidth={2}
|
|
/>
|
|
{/* 数据点 */}
|
|
{dataPoints.map((p, i) => (
|
|
<Circle key={i} cx={p.x} cy={p.y} r={3} fill={colors.primary} />
|
|
))}
|
|
{/* 维度标签 */}
|
|
{dimensions.map((d, i) => {
|
|
const lx = cx + labelR * Math.cos(angleFor(i));
|
|
const ly = cy + labelR * Math.sin(angleFor(i));
|
|
return (
|
|
<SvgText
|
|
key={d.id}
|
|
x={lx}
|
|
y={ly}
|
|
fontSize={10}
|
|
fill={colors.textSecondary}
|
|
textAnchor="middle"
|
|
alignmentBaseline="middle"
|
|
>
|
|
{d.name}
|
|
</SvgText>
|
|
);
|
|
})}
|
|
</Svg>
|
|
);
|
|
}
|
|
|
|
/* ===================== 子组件 ===================== */
|
|
|
|
/** 顶部导航:返回 + 标题 + 分享(onShare 缺省时不渲染分享按钮,避免留下点了没反应的入口) */
|
|
function Header({ onBack, onShare }: { onBack: () => void; onShare?: () => void }) {
|
|
return (
|
|
<View style={styles.header}>
|
|
<Pressable style={styles.headerBtn} onPress={onBack} hitSlop={8}>
|
|
<Ionicons name="chevron-back" size={24} color={colors.textPrimary} />
|
|
</Pressable>
|
|
<Text style={styles.headerTitle}>岗位详情</Text>
|
|
{onShare ? (
|
|
<Pressable style={styles.headerBtnRight} onPress={onShare} hitSlop={8}>
|
|
<Ionicons name="share-social-outline" size={22} color={colors.textPrimary} />
|
|
</Pressable>
|
|
) : (
|
|
<View style={styles.headerBtnRight} />
|
|
)}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
/** 分区标题:竖条装饰 + 标题 + 可选右侧链接 */
|
|
function SectionTitle({
|
|
title,
|
|
link,
|
|
onLink,
|
|
}: {
|
|
title: string;
|
|
link?: string;
|
|
onLink?: () => void;
|
|
}) {
|
|
return (
|
|
<View style={styles.sectionHeader}>
|
|
<View style={styles.sectionBar} />
|
|
<Text style={styles.sectionTitle}>{title}</Text>
|
|
{link ? (
|
|
<Pressable style={styles.sectionLinkBtn} onPress={onLink} hitSlop={8}>
|
|
<Text style={styles.sectionLink}>{link} ></Text>
|
|
</Pressable>
|
|
) : null}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
/* ===================== 页面 ===================== */
|
|
|
|
export default function JobDetailScreen() {
|
|
const { id } = useLocalSearchParams<{ id: string }>();
|
|
const router = useRouter();
|
|
const { detail, overallScore, salaryData, reviews, loading, error, refresh, publishReview } =
|
|
useJobDetail(id);
|
|
const [comment, setComment] = useState('');
|
|
const [publishing, setPublishing] = useState(false);
|
|
|
|
/**
|
|
* 分享岗位:把当前岗位拼成文本经系统分享面板发出。
|
|
* `ok` 只代表面板已拉起,不能据此提示「分享成功」,只在失败时说明原因(见 lib/shareFile)。
|
|
*/
|
|
const handleShare = async () => {
|
|
if (!detail) return;
|
|
const outcome = await shareText(
|
|
buildJobShareText(detail, overallScore, salaryData, reviews.length),
|
|
`${detail.positionName}|${detail.companyName}`,
|
|
);
|
|
if (!outcome.ok) Alert.alert('无法分享', outcome.message);
|
|
};
|
|
|
|
// 发布评价:空内容拦截,成功后清空输入框(列表由 hook 自动刷新)
|
|
const handlePublish = async () => {
|
|
const text = comment.trim();
|
|
if (!text) {
|
|
Alert.alert('提示', '请先输入你的评价内容');
|
|
return;
|
|
}
|
|
setPublishing(true);
|
|
try {
|
|
await publishReview(text);
|
|
setComment('');
|
|
} catch (e) {
|
|
Alert.alert('发布失败', (e as Error).message || '请稍后重试');
|
|
} finally {
|
|
setPublishing(false);
|
|
}
|
|
};
|
|
|
|
// 错误态
|
|
if (error) {
|
|
return (
|
|
<SafeAreaView style={styles.safeArea} edges={['top', 'bottom']}>
|
|
<Header onBack={() => router.back()} />
|
|
<View style={styles.stateWrap}>
|
|
<Text style={styles.stateText}>加载失败,请重试</Text>
|
|
<Pressable style={styles.retryBtn} onPress={refresh}>
|
|
<Text style={styles.retryText}>重试</Text>
|
|
</Pressable>
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
// 加载态
|
|
if (loading || !detail || !overallScore || !salaryData) {
|
|
return (
|
|
<SafeAreaView style={styles.safeArea} edges={['top', 'bottom']}>
|
|
<Header onBack={() => router.back()} />
|
|
<View style={styles.stateWrap}>
|
|
<ActivityIndicator size="large" color={colors.primary} />
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<SafeAreaView style={styles.safeArea} edges={['top', 'bottom']}>
|
|
<Header onBack={() => router.back()} onShare={handleShare} />
|
|
|
|
<ScrollView
|
|
style={styles.scroll}
|
|
contentContainerStyle={styles.content}
|
|
showsVerticalScrollIndicator={false}
|
|
>
|
|
{/* 1. 岗位基本信息 */}
|
|
<View style={styles.card}>
|
|
<View style={styles.basicTop}>
|
|
<Text style={styles.positionName}>{detail.positionName}</Text>
|
|
<View style={styles.statusCol}>
|
|
<View style={styles.statusTag}>
|
|
<Text style={styles.statusText}>{detail.status}</Text>
|
|
</View>
|
|
<Text style={styles.viewsText}>浏览{formatThousands(detail.views)}</Text>
|
|
</View>
|
|
</View>
|
|
<Text style={styles.salary}>
|
|
{detail.salaryMin}-{detail.salaryMax}K · {detail.salaryMonths}薪
|
|
</Text>
|
|
<Text style={styles.metaText}>
|
|
{detail.companyName} · {detail.industry} · {detail.companySize}
|
|
</Text>
|
|
<Text style={styles.metaText}>
|
|
{detail.companyLocation} · {detail.experience} · {detail.education}
|
|
</Text>
|
|
<View style={styles.benefits}>
|
|
{detail.benefits.map((item) => (
|
|
<View key={item} style={styles.benefitTag}>
|
|
<Text style={styles.benefitText}>{item}</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
|
|
{/* 2. 岗位综合评分 */}
|
|
{/* 「评分说明」入口已摘除:项目没有评分规则说明页 */}
|
|
<SectionTitle title="岗位综合评分" />
|
|
<View style={styles.card}>
|
|
<View style={styles.scoreRow}>
|
|
<RadarChart dimensions={overallScore.dimensions} />
|
|
<View style={styles.scoreInfo}>
|
|
<View style={styles.scoreNumberRow}>
|
|
<Text style={styles.scoreNumber}>{overallScore.totalScore}</Text>
|
|
<Text style={styles.scoreUnit}>分</Text>
|
|
</View>
|
|
<View style={styles.levelTag}>
|
|
<Text style={styles.levelTagText}>{overallScore.level}</Text>
|
|
</View>
|
|
<Text style={styles.scoreRank}>{overallScore.rank}</Text>
|
|
</View>
|
|
</View>
|
|
<Pressable style={styles.compareBtn} onPress={() => router.push('/jobs/compare')} hitSlop={6}>
|
|
<Ionicons name="add-circle-outline" size={16} color={colors.primary} />
|
|
<Text style={styles.compareText}>加入对比</Text>
|
|
</Pressable>
|
|
</View>
|
|
|
|
{/* 3. 真实薪资区间 */}
|
|
{/* 「全部」入口已摘除:下面这张卡已经把 4 档经验区间列全了,点进去没有更多内容 */}
|
|
<SectionTitle title="真实薪资区间" />
|
|
<View style={styles.card}>
|
|
{salaryData.ranges.map((range, index) => (
|
|
<View
|
|
key={range.experience}
|
|
style={[styles.salaryRow, index === salaryData.ranges.length - 1 && styles.salaryRowLast]}
|
|
>
|
|
<Text style={styles.salaryExp}>{range.experience}</Text>
|
|
<Text style={styles.salaryRange}>
|
|
{range.min}-{range.max}K
|
|
</Text>
|
|
</View>
|
|
))}
|
|
<Text style={styles.salarySource}>{salaryData.dataSource}</Text>
|
|
</View>
|
|
|
|
{/* 4. 员工评价 */}
|
|
<SectionTitle title="员工评价" />
|
|
{reviews.length === 0 && (
|
|
/* 标题是常驻的,没有这一块时下方会是一片空白,看上去像加载坏了 */
|
|
<View style={styles.emptyCard}>
|
|
<Ionicons name="chatbubble-outline" size={32} color={colors.textHint} />
|
|
<Text style={styles.emptyText}>暂无员工评价</Text>
|
|
<Text style={styles.emptyHint}>成为第一个分享这家公司真实情况的人</Text>
|
|
</View>
|
|
)}
|
|
{reviews.map((review) => (
|
|
<View key={review.id} style={styles.card}>
|
|
<View style={styles.reviewHeader}>
|
|
<Text style={styles.reviewName}>{review.userName}</Text>
|
|
<Text style={styles.reviewRole}>{review.userRole}</Text>
|
|
<Text style={styles.reviewTime}>{review.time}</Text>
|
|
</View>
|
|
<Text style={styles.reviewContent}>{review.content}</Text>
|
|
<View style={styles.reviewTags}>
|
|
{review.tags.map((tag) => (
|
|
<View key={tag} style={styles.reviewTag}>
|
|
<Text style={styles.reviewTagText}>{tag}</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
))}
|
|
</ScrollView>
|
|
|
|
{/* 5. 评论输入框(固定底部) */}
|
|
<View style={styles.commentBar}>
|
|
<TextInput
|
|
style={styles.commentInput}
|
|
placeholder="说说你对这个岗位的看法..."
|
|
placeholderTextColor={colors.textHint}
|
|
value={comment}
|
|
onChangeText={setComment}
|
|
/>
|
|
<Pressable
|
|
style={[styles.publishBtn, publishing && styles.publishBtnDisabled]}
|
|
onPress={handlePublish}
|
|
disabled={publishing}
|
|
>
|
|
{publishing ? (
|
|
<ActivityIndicator size="small" color={colors.white} />
|
|
) : (
|
|
<Text style={styles.publishText}>发布</Text>
|
|
)}
|
|
</Pressable>
|
|
</View>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
safeArea: {
|
|
flex: 1,
|
|
backgroundColor: colors.pageBg,
|
|
},
|
|
stateWrap: {
|
|
flex: 1,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
stateText: {
|
|
marginTop: 12,
|
|
fontSize: 14,
|
|
color: colors.textSecondary,
|
|
},
|
|
retryBtn: {
|
|
marginTop: 16,
|
|
paddingHorizontal: 24,
|
|
paddingVertical: 8,
|
|
borderRadius: 18,
|
|
backgroundColor: colors.primaryBtn,
|
|
},
|
|
retryText: {
|
|
fontSize: 13,
|
|
fontWeight: '600',
|
|
color: colors.white,
|
|
},
|
|
/* ---- 顶部导航 ---- */
|
|
header: {
|
|
height: 48,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
headerTitle: {
|
|
fontSize: 17,
|
|
fontWeight: '700',
|
|
color: colors.textPrimary,
|
|
},
|
|
/**
|
|
* 头部按钮:返回靠左、分享靠右。
|
|
* 原先两者共用一条**只写了 `top`、没写 `left`/`right`** 的 absolute 样式,
|
|
* 在 `justifyContent: 'center'` 的父容器里落到同一处彼此重叠 —— 返回键与分享键
|
|
* 都不在用户预期位置(分享键实测点不到)。absolute 必须成对写清水平锚点。
|
|
*/
|
|
headerBtn: {
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
width: 48,
|
|
height: 48,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
headerBtnRight: {
|
|
position: 'absolute',
|
|
top: 0,
|
|
right: 0,
|
|
width: 48,
|
|
height: 48,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
scroll: {
|
|
flex: 1,
|
|
},
|
|
content: {
|
|
paddingHorizontal: 8,
|
|
paddingBottom: 24,
|
|
},
|
|
card: {
|
|
backgroundColor: colors.white,
|
|
borderRadius: 8,
|
|
padding: 8,
|
|
marginBottom: 8,
|
|
},
|
|
/* ---- 空态 ---- */
|
|
emptyCard: {
|
|
backgroundColor: colors.white,
|
|
borderRadius: 8,
|
|
paddingVertical: 8,
|
|
paddingHorizontal: 8,
|
|
marginBottom: 8,
|
|
alignItems: 'center',
|
|
gap: 8,
|
|
},
|
|
emptyText: {
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: colors.textSecondary,
|
|
},
|
|
emptyHint: {
|
|
fontSize: 12,
|
|
color: colors.textHint,
|
|
textAlign: 'center',
|
|
},
|
|
/* ---- 基本信息 ---- */
|
|
basicTop: {
|
|
flexDirection: 'row',
|
|
alignItems: 'flex-start',
|
|
justifyContent: 'space-between',
|
|
},
|
|
positionName: {
|
|
flex: 1,
|
|
fontSize: 22,
|
|
fontWeight: '700',
|
|
color: colors.textPrimary,
|
|
},
|
|
statusCol: {
|
|
alignItems: 'flex-end',
|
|
marginLeft: 12,
|
|
},
|
|
statusTag: {
|
|
backgroundColor: colors.successLight,
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 3,
|
|
borderRadius: 10,
|
|
},
|
|
statusText: {
|
|
fontSize: 12,
|
|
fontWeight: '600',
|
|
color: colors.successText,
|
|
},
|
|
viewsText: {
|
|
marginTop: 6,
|
|
fontSize: 12,
|
|
color: colors.textHint,
|
|
},
|
|
salary: {
|
|
marginTop: 14,
|
|
fontSize: 20,
|
|
fontWeight: '700',
|
|
color: colors.primary,
|
|
},
|
|
metaText: {
|
|
marginTop: 8,
|
|
fontSize: 13,
|
|
color: colors.textSecondary,
|
|
},
|
|
benefits: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
marginTop: 12,
|
|
},
|
|
benefitTag: {
|
|
backgroundColor: colors.primaryLight,
|
|
borderWidth: 1,
|
|
borderColor: colors.primaryBorder,
|
|
borderRadius: 12,
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 4,
|
|
marginRight: 8,
|
|
marginBottom: 8,
|
|
},
|
|
benefitText: {
|
|
fontSize: 12,
|
|
color: colors.primary,
|
|
},
|
|
/* ---- 分区标题 ---- */
|
|
sectionHeader: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
marginBottom: 12,
|
|
},
|
|
sectionBar: {
|
|
width: 4,
|
|
height: 16,
|
|
borderRadius: 2,
|
|
backgroundColor: colors.primary,
|
|
marginRight: 8,
|
|
},
|
|
sectionTitle: {
|
|
flex: 1,
|
|
fontSize: 17,
|
|
fontWeight: '700',
|
|
color: colors.textPrimary,
|
|
},
|
|
sectionLinkBtn: {
|
|
paddingLeft: 8,
|
|
},
|
|
sectionLink: {
|
|
fontSize: 13,
|
|
color: colors.primary,
|
|
},
|
|
/* ---- 综合评分 ---- */
|
|
scoreRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
scoreInfo: {
|
|
flex: 1,
|
|
alignItems: 'flex-start',
|
|
marginLeft: 8,
|
|
},
|
|
scoreNumberRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'baseline',
|
|
},
|
|
scoreNumber: {
|
|
fontSize: 40,
|
|
fontWeight: '700',
|
|
color: colors.primary,
|
|
},
|
|
scoreUnit: {
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: colors.primary,
|
|
},
|
|
levelTag: {
|
|
marginTop: 4,
|
|
backgroundColor: colors.successLight,
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 4,
|
|
borderRadius: 12,
|
|
},
|
|
levelTagText: {
|
|
fontSize: 13,
|
|
fontWeight: '600',
|
|
color: colors.successText,
|
|
},
|
|
scoreRank: {
|
|
marginTop: 8,
|
|
fontSize: 12,
|
|
color: colors.textSecondary,
|
|
},
|
|
compareBtn: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
alignSelf: 'flex-start',
|
|
marginTop: 16,
|
|
},
|
|
compareText: {
|
|
marginLeft: 4,
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: colors.primary,
|
|
},
|
|
/* ---- 薪资区间 ---- */
|
|
salaryRow: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
paddingVertical: 12,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: colors.borderLight,
|
|
},
|
|
salaryRowLast: {
|
|
borderBottomWidth: 0,
|
|
},
|
|
salaryExp: {
|
|
fontSize: 14,
|
|
color: colors.textSecondary,
|
|
},
|
|
salaryRange: {
|
|
fontSize: 15,
|
|
fontWeight: '700',
|
|
color: colors.textPrimary,
|
|
},
|
|
salarySource: {
|
|
marginTop: 12,
|
|
fontSize: 12,
|
|
color: colors.textHint,
|
|
},
|
|
/* ---- 员工评价 ---- */
|
|
reviewHeader: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
reviewName: {
|
|
fontSize: 14,
|
|
fontWeight: '700',
|
|
color: colors.textPrimary,
|
|
},
|
|
reviewRole: {
|
|
marginLeft: 8,
|
|
fontSize: 12,
|
|
color: colors.textSecondary,
|
|
},
|
|
reviewTime: {
|
|
flex: 1,
|
|
textAlign: 'right',
|
|
fontSize: 12,
|
|
color: colors.textHint,
|
|
},
|
|
reviewContent: {
|
|
marginTop: 10,
|
|
fontSize: 13,
|
|
lineHeight: 20,
|
|
color: colors.textPrimary,
|
|
},
|
|
reviewTags: {
|
|
flexDirection: 'row',
|
|
flexWrap: 'wrap',
|
|
marginTop: 10,
|
|
},
|
|
reviewTag: {
|
|
backgroundColor: colors.pageBg,
|
|
borderWidth: 1,
|
|
borderColor: colors.border,
|
|
borderRadius: 12,
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 4,
|
|
marginRight: 8,
|
|
marginBottom: 8,
|
|
},
|
|
reviewTagText: {
|
|
fontSize: 12,
|
|
color: colors.textSecondary,
|
|
},
|
|
/* ---- 评论输入框 ---- */
|
|
commentBar: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 16,
|
|
paddingVertical: 10,
|
|
backgroundColor: colors.white,
|
|
borderTopWidth: 1,
|
|
borderTopColor: colors.borderLight,
|
|
},
|
|
commentInput: {
|
|
flex: 1,
|
|
height: 40,
|
|
borderRadius: 20,
|
|
backgroundColor: colors.pageBg,
|
|
paddingHorizontal: 16,
|
|
fontSize: 14,
|
|
color: colors.textPrimary,
|
|
},
|
|
publishBtn: {
|
|
marginLeft: 12,
|
|
paddingHorizontal: 18,
|
|
height: 40,
|
|
borderRadius: 20,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
backgroundColor: colors.primaryBtn,
|
|
},
|
|
publishBtnDisabled: {
|
|
opacity: 0.6,
|
|
},
|
|
publishText: {
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: colors.white,
|
|
},
|
|
});
|
|
|